AnsibleでWindows ServerにPowershellスクリプトを実行する
渡辺です。今年の冬は暖かすぎて札幌は春の気配ですね。
AutoScaling時にAnsibleで環境構築を行うでは、Auto ScalingのLifecycle Hookを利用したAnsibleによる環境構築を紹介しました。 今回は対象がWindows Serverであった場合にAnsibleでスクリプトを実行する手順について紹介します。 これらを組み合わせればWindows ServerのAuto Scalingでもフル自動化の扉が開くでしょう!
AnsibleとWindowsリモート管理
基本的にAnsibleは、対象となるサーバにSSHでアクセスして処理(環境構築)を実行します。 Windows Serverでは、デフォルトでSSH接続ができないため、代替手段が必要になります。 代替手段として使われるのは、Windowsリモート管理(WinRM)です。 Windows ServerでWinRMが有効になっていることが、AnsibleでWindowsにアクセスする条件となります。
また、AnsibleでWindowsを操作する場合、Poweshell 3.0以上が必要となります。
詳細は、Ansible - Windows Supportを参照ください。
Windows Serverインスタンスの準備
はじめにWindows Serverのインスタンスを作成します。
Powershellのバージョン確認
現在、Windows Serverのバージョンとしては2012 R2が最新バージョンとなっていますが、2012, 2008 R2, 2008などを利用しなければならないケースもあるでしょう。 それぞれのバージョンでのPowershellのバージョンを確認してたところ、2012 R2ではPowershell 4.0、2012, 2008 R2, 2008ではPowershell 3.0となっています(サービスパック適用済みのため)。 よほど古いAMIから作成したWindow Serverでなければ大丈夫そうですが、確認は必要です。 もし、Powershellのバージョンが3.0未満の場合は3.0以上にアップデートしてください。
なお、Powershellのバージョンは以下のコマンドで確認出来ます。
PS > $PSVersionTable
WinRMのセットアップ
Ansibleで提供しているWinRMのセットアップスクリプトをダウンロードして実行すれば、WinRMが有効になります。
PS > Invoke-WebRequest / > -Uri https://raw.githubusercontent.com/ansible/ansible/devel/examples/scripts/ConfigureRemotingForAnsible.ps1 / > -OutFile ConfigureRemotingForAnsible.ps1 PS > powershell -ExecutionPolicy RemoteSigned .\ConfigureRemotingForAnsible.ps1
Windows Serverのバージョンによって表示されるメッセージは異なりますが、どのバージョンでも問題なく利用できました。
AnsibleからのPowershellスクリプトの実行
WindowsにAnsibleでアクセスするためには、通常のSSHではなくWinRMを利用します。 このため、Ansibleの他に追加のライブラリが必要です。 また、アクセス時にはAdministratorパスワードを利用します。
ここでは、別のAmazon LinuxのEC2インスタンスからAnsibleを実行することを想定していますが、ローカルのMacから実行する場合でも変わりません。 Ansibleはインストール済みとします。
pywinrmのインストール
AnsibleのWindowsモジュールが依存するPythonでWinRMを扱うライブラリpywinrmをpipでインストールします。
$ pip install pywinrm
Inventoryファイルの作成
適当なディレクトリにInventoryファイル(hosts)を作成します。
[windows] ec2-54-178-xxx-xxx.ap-northeast-1.compute.amazonaws.com
winsowsというグループを作成し、Windows ServerのPublic DNSを設定しました。
group_varsファイルの作成
windowsグループのための変数ファイル(group_vars/windows.yml)を作成します。 SSH UserとSSH PasswordにはWindowsのログイン情報を記入してください。
sible_ssh_user: Administrator ansible_ssh_pass: PASSWORD_FOR_ADMIN ansible_ssh_port: 5986 ansible_connection: winrm
なお、複数のWindowsサーバにアクセスする場合、デフォルトではログインパスワードがサーバ毎に異なる点に注意してください。
セキュリティグループの設定
WinRMは5986ポートで通信を行うため、セキュリティグループの設定でAnsibleを実行するマシンからの5986ポートを許可します。
疎通確認
最低限の設定は完了したので、Windowsモジュールのwin_pingを利用して疎通確認します。
$ ansible windows -i hosts -m win_ping -vvv
疎通に失敗する場合は、セキュリティグループ(ポート)とWindowsパスワードを確認してみてください。 特にWindowsパスワードが間違っている場合にHTTPエラーのようなメッセージが表示されて混乱します。
Powershellスクリプトの実行
Playbook(playbool.yml)を用意してPowershellスクリプトを実行してみます。 Playbookでは、Powershellのスクリプトを対象のサーバで実行させます。
- hosts: windows gather_facts: false tasks: - name: output ec2-instance info to text file script: files/get-ec2-instance.ps1
Powershellスクリプト(files/get-ec2-instance.ps1)を配置します。
Get-EC2Instance -Region ap-northeast-1 | Out-File -FilePath C:/temp/ec2.txt
このスクリプトでは、AWS SDK for Powershellを利用し、EC2インスタンスの情報をファイルに出力しています。
実行してみましょう。
# ansible-playbook -i hosts playbook.yml
まとめ
Windows ServerにWinRMをセットアップすることで、AnsibleからPowershellスクリプトを流し込むことができます。 ファイルの転送を行ったりすることが難しいため、リソースは外部サーバからダウンロードするなど、工夫は必要となりますが、Poweshellでできる範囲であればWindows Serverを自由自在に操作できるでしょう。
とはいえ、簡単に検証した範囲では他のWinodows系モジュールの動作はまだ不安定なようです(Ansibel 1.8.4時点)。 サービスの起動や停止も可能なのですが、成功したり失敗したりと微妙な挙動でした。 Windowsサポートがはじまったのも最近のようですので今後の安定化が期待されます。